﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MethodWorx.CMS.TemplateParser
{
    public class TemplateOffset
    {
        public int TemplateIndex { get; set; }
        public int StartOffset { get; set; }
        public int EndOffset { get; set; }
    }
    public class TemplateFlattener
    {
        //private StringBuilder flattenedTemplate;
        private XmlParser parser;


        public TemplateFlattener(params string[] templates)
            : this(null, templates)
        {

        }

        public TemplateFlattener( string placeholderName, params string[] templates)
        {

            this.FlattenTemplates(templates, placeholderName);
        }



        private void FlattenTemplates(string[] templates, string placeholderName)
        {
            List<string> listOfTemplates = new List<string>(templates);
            int offset = 0;
            int index = 0;
            int contentOffset = 0;

            //  start at template 0
            //  and work upwards
            //  replacing <placeholder containers> with <placeholder> content
            parser = new XmlParser(templates[0]);

            for (var i = 0; i < templates.Length - 1; i++ )
            {
                
                //  
                List<TemplateElement> containers =
                    parser.Document.FindElements("placeholder", true).Where(p => p.HasAttribute("type", "container", true)).
                        ToList();

                //  
                //  all the containers now present, we need to repalce them all
                foreach(var element in containers)
                {
                    //  this is what we want
                    //  lets get the attribute value
                    var name = element.GetAttributeValue("name", "", true);
                    if (string.IsNullOrEmpty(name))
                        throw new ParserException("Missing Name Attribute For Placeholder");

                    var content = this.GetPlaceholderContent(templates[i + 1], name);
                    if (content != null)
                    {
                        if(!string.IsNullOrEmpty(placeholderName) && name.ToLower() == placeholderName.ToLower())
                        {
                            parser = new XmlParser(content.InnerXml);
                            return;
                        }

                        int removed = element.Remove();
                        element.Parent.InsertAt(content.Children.Where(c => !(c is TemplateAttribute)), removed);
                    }
                }
            }

            if(!string.IsNullOrEmpty(placeholderName))
            {
                var content = this.GetPlaceholderContent(parser.Document.OuterXml, placeholderName);
                if (content != null)
                {
                    if (!string.IsNullOrEmpty(placeholderName))
                    {
                        parser = new XmlParser(content.InnerXml);
                        return;
                    }
                }
                //  now search through the other templates
                foreach(var template in templates)
                {
                    content = this.GetPlaceholderContent(template, placeholderName);
                    if (content != null)
                    {
                        if (!string.IsNullOrEmpty(placeholderName))
                        {
                            parser = new XmlParser(content.InnerXml);
                            return;
                        }
                    }
                }
                parser = new XmlParser("");
            }
        }

        private TemplateElement GetPlaceholderContent(string template, string name)
        {
            if(!string.IsNullOrEmpty(template))
            {
                // 
                //  ok, this has one 
                var parser = new XmlParser(template);
                foreach (var container in parser.Document.FindElements("placeholder", true))
                {
                    if (container.HasAttribute("type", "content", true) && container.HasAttribute("name", name, true))
                    {
                        //  this is the content
                        return container;
                    }
                }
            }
            return null;
        }

        public XmlParser Parser
        {
            get { return this.parser; }
        }

    }

}
